package com.linln.modules.system.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.linln.common.utils.UUIDGenerator;
import com.linln.modules.system.dao.CustomMapper;
import com.linln.modules.system.dao.UserAccountDetailMapper;
import com.linln.modules.system.dao.UserBillMapper;
import com.linln.modules.system.dao.UserInviteMapper;
import com.linln.modules.system.dao.UserPointAccountMapper;
import com.linln.modules.system.dao.WxUserMapper;
import com.linln.modules.system.entity.UserAccountDetail;
import com.linln.modules.system.entity.UserBill;
import com.linln.modules.system.entity.UserBillExample;
import com.linln.modules.system.entity.UserInvite;
import com.linln.modules.system.entity.UserInviteExample;
import com.linln.modules.system.entity.UserPointAccount;
import com.linln.modules.system.entity.UserPointAccountExample;
import com.linln.modules.system.entity.WxUser;
import com.linln.modules.system.vo.admins.AdminUserBillVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class BillServices {

    @Autowired
    private WxUserMapper wxUserMapper;

    @Autowired
    private UserBillMapper billMapper;

    @Autowired
    private CustomMapper customMapper;

    @Autowired
    private UserPointAccountMapper pointAccountMapper;

    @Autowired
    private UserAccountDetailMapper accountDetailMapper;

    @Autowired
    private UserInviteMapper userInviteMapper;

//    public Page<WxUser> getIndexWxUser(Integer pageNum, Integer pageSize, String name) {
//        PageHelper.startPage(pageNum, pageSize, true);
//        Page<WxUser> pager = wxUserMapper.getAllWxUserPager(name);
//        return pager;
//    }

    public Page<AdminUserBillVo> getUserBillVoPager(Integer pageNum, Integer pageSize, String startTime, String endTime, String nickName,Integer state) throws Exception {
        PageHelper.startPage(pageNum, pageSize, true);
        Page<AdminUserBillVo> voPager = customMapper.getUserBillVoPager(startTime, endTime, nickName,state);
        long total = voPager.getTotal();
        if (total > 1) {
            List<AdminUserBillVo> result = voPager.getResult();
            result.forEach(au -> {
                int states = au.getStates();
                if (states == 0) {
                    au.setStatus("待审核");
                } else if (states == 1) {
                    au.setStatus("审核不通过");
                } else if (states == 2) {
                    au.setStatus("审核通过");
                } else {
                    au.setStatus("审核不通过");
                }
            });
        }
        return voPager;
    }

    public UserBill getUserBillByKeyId(String id) {
        UserBill bill = billMapper.selectByPrimaryKey(id);
        return bill;
    }

    @Transactional
    public Map<String, Object> updateUserBill(Integer oldState, UserBill userBill) {
        Integer states = userBill.getStates();
        HashMap<String, Object> hashMap = new HashMap<>();
        if (oldState == 1 && states == 2) {
            hashMap.put("code", 1);
            hashMap.put("msg", "未通过的订单不可重复操作");
        } else if (oldState == 0 && states == 2) {
            Date date = new Date();
            String userId = userBill.getUserId();
            UserPointAccount account = getPointAccountByUserId(userId);
            //  todo  1 代表冻结
            if (account != null && account.getState() == 0) {
                Integer points = account.getPoints();
                List<UserBill> multi = getUserBillMulti(userBill.getOldCode(), 2);
                if(!multi.isEmpty()){
                    userBill.setUpdateTime(new Date()).setStates(1).setPoints(userBill.getAmount().multiply(new BigDecimal(0.6)).toBigInteger().intValue());
                    userBill.setRemark("该凭证单号重复!");
                    billMapper.updateByPrimaryKeySelective(userBill);
                    hashMap.put("msg","已存在该凭证单号,并审核为不通过状态");
                    hashMap.put("code",200);
                } else {
                    // todo kinds 0 代表消费  1 新人注册赠送  2 兑换
                    // todo states 0 正常


                    List<UserInvite> userInvites = getUserInvite(userId);
                    List<UserBill> successBill = getUserBillSuccess(userId, 2);
                    WxUser user = wxUserMapper.selectByPrimaryKey(userId);
                    if(successBill.isEmpty() || (!successBill.isEmpty()&& successBill.size()==1) ){
                        if(!userInvites.isEmpty()){
                            String fromUserId = userInvites.get(0).getFromUser();
                            UserPointAccount fromUserAccount = getPointAccountByUserId(fromUserId);
                            Integer fromUserOldPoints = fromUserAccount.getPoints();
                            UserAccountDetail fromUserAccountDetail = new UserAccountDetail();
                            fromUserAccountDetail.setId(UUIDGenerator.generate()).setCreateTime(date).setAccountId(fromUserAccount.getId())
                                    .setKinds(4).setPoints(userBill.getAmount().multiply(new BigDecimal(0.6)).toBigInteger().intValue()/2)
                                    .setRemark("好友("+user.getNickName()+")首次消费赠送").setStates(0).setUserId(fromUserId); // TODO 首次送积分,一半
                            fromUserAccountDetail.setSurplusPoints(fromUserOldPoints+ fromUserAccountDetail.getPoints());
                            fromUserAccount.setPoints(fromUserOldPoints+ fromUserAccountDetail.getPoints());
                            fromUserAccount.setUpdateTime(date);
                            accountDetailMapper.insert(fromUserAccountDetail);
                            pointAccountMapper.updateByPrimaryKeySelective(fromUserAccount);
                        }
                    }

                    UserAccountDetail accountDetail = new UserAccountDetail();
                    accountDetail.setId(UUIDGenerator.generate()).setCreateTime(date).setAccountId(account.getId())
                            .setKinds(2).setPoints(userBill.getAmount().multiply(new BigDecimal(0.6)).toBigInteger().intValue())
                            .setRemark("凭证换积分" + userBill.getOldCode()).setStates(0).setUserId(userId);
                    account.setPoints(points + accountDetail.getPoints());
                    accountDetail.setSurplusPoints(points + accountDetail.getPoints());
                    account.setUpdateTime(date);
                    userBill.setUpdateTime(new Date()).setPoints(userBill.getAmount().multiply(new BigDecimal(0.6)).toBigInteger().intValue());
                    billMapper.updateByPrimaryKeySelective(userBill);
                    accountDetailMapper.insert(accountDetail);
                    pointAccountMapper.updateByPrimaryKeySelective(account);

                    hashMap.put("code",200);
                    hashMap.put("msg", "操作成功!");
                }
            } else if (account != null && account.getState() == 0) {
                hashMap.put("code", 1);
                hashMap.put("msg", "账户已冻结,不可操作");
            } else {
                hashMap.put("code", 1);
                hashMap.put("msg", "账户异常");
            }
        } else if (oldState == 0 && states == 1) {
            userBill.setUpdateTime(new Date());
            billMapper.updateByPrimaryKeySelective(userBill);
            hashMap.put("code",2);
            hashMap.put("msg", "操作成功!");
        }
        return hashMap;
    }

    private UserPointAccount getPointAccountByUserId(String userId) {
        UserPointAccountExample example = new UserPointAccountExample();
        example.createCriteria().andUserIdEqualTo(userId).andDeletedEqualTo(0);

        List<UserPointAccount> accounts = pointAccountMapper.selectByExample(example);
        if (!accounts.isEmpty()) {
            return accounts.get(0);
        }
        return null;
    }


    private List<UserBill> getUserBillMulti(String oldCode,Integer states){
        UserBillExample example = new UserBillExample();
        example.createCriteria().andOldCodeEqualTo(oldCode).andStatesEqualTo(states);

        List<UserBill> list = billMapper.selectByExample(example);
        return list;
    }

    private List<UserBill> getUserBillSuccess(String userId,Integer states){
        UserBillExample example = new UserBillExample();
        example.createCriteria().andUserIdEqualTo(userId).andStatesEqualTo(states);

        List<UserBill> list = billMapper.selectByExample(example);
        return list;
    }

    public List<UserInvite> getUserInvite(String userId){
        UserInviteExample example = new UserInviteExample();
        example.createCriteria().andToUserEqualTo(userId);
        List<UserInvite> list = userInviteMapper.selectByExample(example);
        return list;
    }
}
